/**
 * @Author: wzx
 * @Description:
 * @Version: 1.0.0
 * @Date: 2021/5/31 上午4:18
 *@Copyright: MIN-Group；国家重大科技基础设施——未来网络北大实验室；深圳市信息论与未来网络重点实验室
 */

package authservice

import (
	"context"
	"fmt"
	"math/rand"
	"time"
	"vpn-management-server/cache"
	"vpn-management-server/config"
	"vpn-management-server/logger"
	"vpn-management-server/network"
	"vpn-management-server/security/code"
)

var sessionList *cache.Cache

func Init(config config.SessionConfig) {
	sessionList = cache.NewWithPath("sess", config.DefaultExpiration, config.CleanupInterval, config.CachePath)
}

func SetSession(ctx context.Context, object interface{}, response *network.NetResponse) {
	sessionId := fmt.Sprintf("%16v", rand.New(rand.NewSource(time.Now().UnixNano())).Int63n(1e16))
	response.Header["SessionId"] = sessionId
	sessionList.SetDefault(sessionId, object)
}

func AuthSession(ctx context.Context, request *network.NetRequest, resp *network.NetResponse) bool {
	// TODO 如果header中没有sessionID的话 报错 没有授权
	if _, ok := request.Header["SessionId"]; ok == false {
		resp.Code = code.UNAUTHORIZED
		logger.Logger.Error("not have sessionId")
		resp.ErrorMsg = "not have sessionId"
		return false
	}
	// TODO 如果存入的不是字符串 或者没有数据的话 报错 禁止
	sessionId, ok := request.Header["SessionId"].(string)
	if !ok {
		logger.Logger.Error("sessionId is not string")
		resp.Code = code.FORBIDDEN
		resp.ErrorMsg = "sessionId is not string"
		return false
	}
	// TODO 得到SessionID 得到成功在request中设置名字属性 否则失效 返回false
	if object, ok := sessionList.Get(sessionId); !ok {
		logger.Logger.Error("the sessionId expired")
		resp.Code = code.FORBIDDEN
		resp.ErrorMsg = "the sessionId expired"
		return false
	} else {
		// 更新过期时间
		sessionList.SetDefault(sessionId, object)
		request.SetAttribute("admin", object)
		return true
	}
}
